package aupdg.presentation;

import aupdg.data.model.Node;
import java.util.*;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;

/**
 * Implements the listener for the information leak originator's tables.
 *
 * @author AA and CJ
 */
public class SelectionListener implements ListSelectionListener {

    private JTabbedPane pAnalysisDetails;
    private JTable ilTable;
    private Map ilMap;
    private String prefix;
    private Map<String, Integer> createdTabs;

    // It is necessary to keep the table since it is not possible
    // to determine the table from the event's source
    SelectionListener(String prefix, JTabbedPane pAnalysisDetails, JTable ilTable, Map ilMap) {
        this.pAnalysisDetails = pAnalysisDetails;
        this.ilTable = ilTable;
        this.ilMap = ilMap;
        this.prefix = prefix;
        this.createdTabs = new HashMap();
    }

    /**
     * The class gets a map with the information leaks (key is the originator,
     * value is the whole chain containing the violation). This method sets the
     * map.
     *
     * @param ilMap
     */
    public void setInnerMap(Map ilMap) {
        this.ilMap = ilMap;
        this.createdTabs = new HashMap();
    }

    /**
     * This method implements the action when the user clicks on a cell in the
     * information leaks table. When this happens the panel pAnalysisDetails
     * that shows the chain of event opens a new tab if this was not previously
     * opened or selects it if this was already opened.
     *
     * @param e
     */
    @Override
    public void valueChanged(ListSelectionEvent e) {

        if (!e.getValueIsAdjusting()) {
            if (ilMap != null && ilTable != null) {
                int rowIndex = ilTable.getSelectedRow();
                int colIndex = ilTable.getSelectedColumn();

                //Creation of Table
                JTable findingsTable = new JTable();
                findingsTable.setCursor(new java.awt.Cursor(java.awt.Cursor.DEFAULT_CURSOR));
                //findingsTable.setShowHorizontalLines(false);
                //findingsTable.setShowVerticalLines(false);

                //Creation of Table model. This fills the table with the findings
                //from the map

                DefaultTableModel findingsTableModel = new DefaultTableModel();
                //Only one column
                findingsTableModel.addColumn(new Object[]{});
                findingsTable.setTableHeader(null);
                findingsTable.setModel(findingsTableModel);

                //We retrieve the list of nodes from the map, convert it to an array
                //so that it can be added to the table.
                System.out.println("INVOKING GET VALUE AT:");
                System.out.println(rowIndex);
                System.out.println(colIndex);

                if (rowIndex != -1 && colIndex != -1) {
                    String originatorLabel = (String) ilTable.getValueAt(rowIndex, colIndex);
                    System.out.println(originatorLabel + " SELECTED");
                    List<List<Node>> findingsLists = new ArrayList<List<Node>>();
                    List<String> renderedLists = new ArrayList();

                    Iterator keyIt = ilMap.keySet().iterator();
                    while (keyIt.hasNext()) {
                        Node keyNode = (Node) keyIt.next();
                        if (originatorLabel.equals(keyNode.toString())) {
                            findingsLists = (List) ilMap.get(keyNode);
                        }
                    }

                    for (int i = 0; i < findingsLists.size(); i++) {
                        List<Node> listOfNodes = findingsLists.get(i);
                        String leakCell = new String();
                        for (int j = 0; j < listOfNodes.size(); j++) {
                            Node currentiNodeInfo = listOfNodes.get(j);
                            leakCell = leakCell + currentiNodeInfo.toString() + " ("
                                    + currentiNodeInfo.getLevel() + ")";
                            if (!(j == listOfNodes.size() - 1)) {
                                leakCell = leakCell + " -> ";
                            }
                        }
                        renderedLists.add(leakCell);
                        findingsTableModel.addRow(new Object[]{leakCell});
                    }

                    //We create a scrollPane to add the table on
                    JScrollPane scrollPane = new JScrollPane(findingsTable);

                    //If the tab was not created we add it
                    String tabName = prefix + ": " + originatorLabel;
                    if (createdTabs.containsKey(tabName)) {
                        pAnalysisDetails.setSelectedIndex(createdTabs.get(tabName));
                    } else {
                        pAnalysisDetails.addTab(tabName, scrollPane);
                        pAnalysisDetails.setSelectedIndex(pAnalysisDetails.getTabCount() - 1);
                        createdTabs.put(tabName, pAnalysisDetails.getTabCount() - 1);
                    }
                }
            }
        }
    }
}